package br.com.suricattus.util.string;

import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * Classe utilitaria para CNPJ
 * 
 * @author lucas lins
 *
 */
public abstract class CnpjUtil {

	private static List<String> INVALIDOS = Arrays.asList(new String []{"00000000000000", "11111111111111", "22222222222222", "33333333333333", 
																		"44444444444444", "55555555555555", "66666666666666", "77777777777777", 
																		"88888888888888", "99999999999999"});
	
	
	/**
	 * Verifica se o cnpj e valido
	 * @param cnpj
	 * @return
	 */
	public static boolean isValido(String cnpj) {
		if(cnpj == null) return false;
		
		cnpj = cnpj.trim();
		if(cnpj.length() == 0) return false;
		
		cnpj = unformat(cnpj);
		if(!Pattern.matches("\\d{14}", cnpj)) return false;
		
		if(INVALIDOS.contains(cnpj)) return false;
		
		char charsCNPJ[] = cnpj.toCharArray();
		int dv1 = getPrimeiroDV(charsCNPJ);
		int dv2 = getSegundoDV(charsCNPJ, dv1);
		
		return Character.getNumericValue(charsCNPJ[12]) == dv1 && Character.getNumericValue(charsCNPJ[13]) == dv2;
	}

	/**
	 * Remove a mascara do cnpj
	 * @param cnpj
	 * @return
	 */
	public static String unformat(String cnpj){
		return cnpj.replace(".", "").replace("/", "").replace("-", "");
	}
	
	/**
	 * Mascara o cnpj
	 * @param cnpj
	 * @return
	 */
	public static String format(String cnpj){
		return String.format("%s.%s.%s/%s-%s", cnpj.substring(0, 2), cnpj.substring(2, 5), cnpj.substring(5, 8), cnpj.substring(8, 12), cnpj.substring(12, 14));
	}
	
	/**
	 * Calcula o primeiro DV do cnpj
	 * @param charsCNPJ
	 * @return
	 */
	private static int getPrimeiroDV(char[] charsCNPJ) {
		int fator = 5;
		int soma = 0;
		for (int i = 0; i < charsCNPJ.length - 2; i++) {
			char c = charsCNPJ[i];
			soma += Integer.parseInt(String.valueOf(c)) * fator;
			if (i == 3){
				fator = 9;
			}else{
				fator--;
			}
		}

		int valor = (soma) % 11;

		int digito1 = 11 - valor;
		if ((soma) % 11 < 2) {
			digito1 = 0;
		}
		return digito1;
	}

	/**
	 * Calcula o segundo DV do cnpj
	 * @param charsCNPJ
	 * @param digito1
	 * @return
	 */
	private static int getSegundoDV(char[] charsCNPJ, int dv1) {
		int fator2 = 6;
		int soma2 = 0;
		for (int i = 0; i < charsCNPJ.length - 2; i++) {
			char c = charsCNPJ[i];
			soma2 += Integer.parseInt(String.valueOf(c)) * fator2;
			if (i == 4){
				fator2 = 9;
			}else{
				fator2--;
			}
		}
		soma2 += dv1 * 2;
		int valor2 = (soma2) % 11;

		int digito2 = 11 - valor2;
		if ((soma2) % 11 < 2)
			digito2 = 0;
		return digito2;
	}
	
}
